// import type { DescriptionsProps } from "antd/es/descriptions";
import { useEffect, useMemo, useRef, useState, type CSSProperties } from "react";
import { get } from "lodash-es";
import { Descriptions } from "antd";
import type { DescInstance, DescItem, DescriptionProps } from "./typing";
// import type { CollapseContainerOptions } from "@/components/Container";
// import { CollapseContainer } from "@/components/Container";
import { isFunction } from "@/utils/is";
import { deepMerge } from "@/utils";
import "./Description.less";
import { DescriptionPropsType, DescriptionDefaultProps } from "./props";

interface ComponentProps {
	register?: Fn;
}
const Description = (props: DescriptionPropsType & ComponentProps) => {
	// fix React18 "defaultProps" problem
	props = Object.assign({}, { ...DescriptionDefaultProps, ...props });

	const [propsRef, setPropsRef] = useState<Partial<DescriptionProps> | null>({});
	const lastPropsRef = useRef<Partial<DescriptionProps> | null>({});

	const prefixCls = "description";

	// Custom title component: get title
	const getMergeProps = useMemo(() => {
		return {
			...props,
			...propsRef
		};
	}, [propsRef]);

	const getProps = useMemo(() => {
		const opt = {
			...getMergeProps
			// title: undefined
		};
		return opt;
	}, [getMergeProps]);

	/**
	 * @description: Whether to setting title
	 */
	// const useWrapper = useMemo(() => !!getMergeProps.title, [getMergeProps]);

	/**
	 * @description: Get configuration Collapse
	 */
	// const getCollapseOptions = useMemo((): CollapseContainerOptions => {
	// 	return {
	// 		// Cannot be expanded by default
	// 		canExpand: false,
	// 		...getProps.collapseOptions
	// 	};
	// }, [getProps?.collapseOptions]);

	const getDescriptionsProps = useMemo(() => {
		return { ...getProps };
	}, [getProps]);

	// Prevent line breaks
	function renderLabel({ label, labelMinWidth, labelStyle }: DescItem) {
		if (!labelStyle && !labelMinWidth) return label;

		const labelStyles: CSSProperties = {
			...labelStyle,
			minWidth: `${labelMinWidth}px `
		};
		return <div style={labelStyles}>{label}</div>;
	}

	// const renderContainer = () => {
	// 	const content = props.useCollapse ? renderDesc() : <div>{renderDesc()}</div>;
	// 	// Reduce the dom level
	// 	if (!props.useCollapse) return content;

	// 	const { canExpand, helpMessage } = getCollapseOptions;
	// 	const { title } = getMergeProps;

	// 	return (
	// 		<CollapseContainer title={title} canExpan={canExpand} helpMessage={helpMessage}>
	// 			{{
	// 				default: () => content,
	// 				action: () => getSlot(slots, "action")
	// 			}}
	// 		</CollapseContainer>
	// 	);
	// };

	// set newest props
	function setDescProps(descProps: Partial<DescriptionProps>): void {
		setPropsRef(deepMerge(lastPropsRef.current || {}, descProps) as Recordable);
	}

	const methods: DescInstance = {
		setDescProps
	};

	/** Effect */

	useEffect(() => {
		lastPropsRef.current = propsRef;
	}, [propsRef]);

	useEffect(() => {
		props.register && props.register(methods);
		return () => {
			// clean
			setPropsRef(null);
			lastPropsRef.current = null;
		};
	}, []);

	/** Render */

	function renderItem() {
		const { schema, data } = getProps;
		return schema
			.map((item: any) => {
				const { render, field, span, show, contentMinWidth } = item;

				if (show && isFunction(show) && !show(data)) return null;

				const getContent = () => {
					const _data = getProps?.data;
					if (!_data) return null;

					const getField = get(_data, field);
					// eslint-disable-next-line no-prototype-builtins
					if (getField && !_data.hasOwnProperty(field)) return isFunction(render) ? render("", _data) : "";

					return isFunction(render) ? render(getField, _data) : getField ?? "";
				};

				const width = contentMinWidth;

				const renderDescriptionsItem = () => {
					if (!contentMinWidth) return getContent();

					const style: CSSProperties = {
						minWidth: `${width}px`
					};
					return <div style={style}>{getContent()}</div>;
				};
				return (
					<Descriptions.Item label={renderLabel(item)} key={field} span={span}>
						{renderDescriptionsItem()}
					</Descriptions.Item>
				);
			})
			.filter(item => !!item);
		// });
	}

	const renderDesc = () => {
		return (
			<Descriptions className={`${prefixCls}`} {...(getDescriptionsProps as any)}>
				{renderItem()}
			</Descriptions>
		);
	};

	// return useWrapper ? renderContainer() : renderDesc();
	return renderDesc();
};

export default Description;
